#pragma once

#include "stdafx.h"

#include <math.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "VideoFrameView.h"


void DecoderInit(int width, int height, void* pParam)
{
	// 1. Declare variable that use in decode and encode.
	VideoFrameView* pVFV = (VideoFrameView *)pParam;
	int pic_size;


	const int clip_width = width;
	const int clip_height = height;


	avcodec_register_all();

	// 2. Initial codec/picture structure for decoder.

	pVFV->m_pCodecDecode = avcodec_find_decoder(CODEC_ID_H264);
	if (!pVFV->m_pCodecDecode) {
	fprintf(stderr, "codec not found\n");
	exit(1);
	}

//	ctxDecode= avcodec_alloc_context();
	pVFV->m_pCtxDecode= avcodec_alloc_context3(NULL);
//	avcodec_get_context_defaults(ctxDecode);
	avcodec_get_context_defaults3(pVFV->m_pCtxDecode, NULL);
	pVFV->m_pCtxDecode->flags2 |= CODEC_FLAG2_FAST;
	pVFV->m_pCtxDecode->pix_fmt = PIX_FMT_YUV420P;
	pVFV->m_pCtxDecode->width = clip_width;
	pVFV->m_pCtxDecode->height = clip_height; 
//	ctxDecode->dsp_mask = (FF_MM_MMX | FF_MM_MMXEXT | FF_MM_SSE);

//	if (avcodec_open(ctxDecode, codecDecode) < 0) {
	if (avcodec_open2(pVFV->m_pCtxDecode, pVFV->m_pCodecDecode, NULL) < 0) {
	fprintf(stderr, "could not open codec\n");
	exit(1);
	}

	pVFV->m_pPictureDecoded= av_frame_alloc();
	av_frame_unref(pVFV->m_pPictureDecoded);
	
	pic_size = avpicture_get_size(PIX_FMT_YUV420P, clip_width, clip_height);

	// sws....
	pVFV->m_pSwscale_context = sws_getContext(clip_width, clip_height, AV_PIX_FMT_YUV420P,
                                                 clip_width, clip_height, AV_PIX_FMT_BGR24,
                                                 SWS_BICUBIC, NULL, NULL, NULL);
    if (!pVFV->m_pSwscale_context) {
        fprintf(stderr, "Failed to create the swscale context for the YCbCr->RGB conversion\n");
    }
}

#if 0 /*jhbae*/
void DecoderDeinit(void)
{
//	sws_freeContext(swscale_context);

	avcodec_close(ctxDecode);
	av_free(ctxDecode);
	av_free(pictureDecoded);  
}
#endif

// bool DecoderDecodeBitstream(unsigned char* bits, int length)
bool DecoderDecodeBitstream(void* pParam)
{
	VideoFrameView* pVFV = (VideoFrameView *) pParam;
	AVPacket avpkt;
	int got_picture, len;

	avpkt.size = pVFV->m_pcapCapture.SecondFramePos;
	avpkt.data = pVFV->m_pcapCapture.pBufferH264;

	len = avcodec_decode_video2(pVFV->m_pCtxDecode, pVFV->m_pPictureDecoded, &got_picture, &avpkt);

	if (len < 0) {
		printf("Error while decoding frame\n");
//		exit(1);
	}

	if (got_picture) {
		printf("len = %d saving frame\n", len);

		sws_scale(pVFV->m_pSwscale_context, pVFV->m_pPictureDecoded->data, pVFV->m_pPictureDecoded->linesize, 0, pVFV->m_pPictureDecoded->height,
				(uint8_t**)&(pVFV->m_drawer.pbmpdata), pVFV->m_drawer.pbmplinesize);
		return true;
	}
	else
	{
		return false;
	}
}
